/*
 * vmbdoor.cpp
 */

#include "vmbdoor.h"

/*
 *	Because direct I/O access is a privileged instruction,
 *	exception handling is requied for VMware backdoor
 *	operation to work in Windows NT/2000 32 bit environment,
 */

#ifdef _WIN32
#include <excpt.h>
#endif

/*
 * executes VMware backdoor I/O function call
 */

int VMBackDoor(
	uint32 *reg_a,
	uint32 *reg_b,
	uint32 *reg_c,
	uint32 *reg_d)
{
	uint32 a, b, c, d;
	
	b = reg_b ? *reg_b : 0;
	c = reg_c ? *reg_c : 0;

#ifdef _WIN32
	__try {
#endif
		__asm {
			push eax
			push ebx
			push ecx
			push edx
			
			mov eax, VMWARE_MAGIC
			mov ebx, b
			mov ecx, c
			mov edx, VMWARE_PORT
			
			in eax, dx
			
			mov a, eax
			mov b, ebx
			mov c, ecx
			mov d, edx
			
			pop edx
			pop ecx
			pop ebx
			pop eax
		}
#ifdef _WIN32
	} __except (EXCEPTION_EXECUTE_HANDLER) {}
#endif
	
	if (reg_a) *reg_a = a;
	if (reg_b) *reg_b = b;
	if (reg_c) *reg_c = c;
	if (reg_d) *reg_d = d;
	
	return a;	/* in 32 bit version, this is the same value as *reg_a.		*/
				/* in 16 bit version, this is low word of the same value.	*/
}

/*
 * Check VMware version only
 */
 
int VMGetVersion()
{
	uint32 version, magic, command;
	
	command = VMCMD_GET_VERSION;
	
	VMBackDoor(&version, &magic, &command, NULL);
	
	if (magic == VMWARE_MAGIC) {
		return version;
	}
	else {
		return 0;
	}
}
/* End of File */
